package icu.twtool.database

import icu.twtool.database.model.ExerciseMetaData
import icu.twtool.database.model.PracticeRecord
import icu.twtool.util.PathUtil
import java.sql.Connection
import java.sql.DriverManager
import java.util.Collections
import kotlin.io.path.absolutePathString

/**
 * 数据库连接工具
 * @author Wen
 * @since 2022-11-02
 */
object DatabaseUtil {

    private val connections = Collections.synchronizedList(mutableListOf<Connection>())

    init {
        Class.forName("org.h2.Driver")
        ExerciseMetaData.init()
        PracticeRecord.init()
    }

    fun <R> connection(action: Connection.() -> R): R? {
        return try {
            val connection =
                connections.removeFirstOrNull()?.run {
                    if (createStatement().execute("select 1")) this else null
                } ?: DriverManager.getConnection("jdbc:h2:" + PathUtil.data().resolve("data").absolutePathString())
            val result = connection.action()
            connections.add(connection)
            result
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }
    fun <R> transactionConnection(action: Connection.() -> R): R? {
        return try {
            val connection =
                connections.removeFirstOrNull()?.run {
                    if (createStatement().execute("select 1")) this else null
                } ?: DriverManager.getConnection("jdbc:h2:" + PathUtil.data().resolve("data").absolutePathString())
            connection.autoCommit = false
            val result = try {
                val r = connection.action()
                connection.commit()
                r
            } catch (e: Exception) {
                e.printStackTrace()
                connection.rollback()
                null
            }
            connections.add(connection)
            result
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

}